package com.company.project.robot.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.company.project.common.exception.BusinessException;
import com.company.project.common.utils.ExcelUtils;
import com.company.project.robot.entity.JokesEntity;
import com.company.project.robot.entity.LanternRiddlesEntity;
import com.company.project.robot.mapper.JokesMapper;
import com.company.project.robot.service.JokesService;
import com.company.project.robot.vo.ReptilesVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;


@Slf4j
@Service("jokesService")
public class JokesServiceImpl extends ServiceImpl<JokesMapper, JokesEntity> implements JokesService {

    /**
     * 导出模板
     *
     * @param request
     * @param response
     * @throws IOException
     */
    @Override
    public void exportExcel(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String[] excelHeader = {"内容", "喜欢人数", "备注"};
        String[] columnNames = {"tEXT", "love", "remake"};
        int[] ds_format = {2, 2, 2};
        String[] sumColumns = {"", "", ""};
        ExcelUtils.export("笑话导入模板.xlsx", null, excelHeader, columnNames, sumColumns, ds_format, null,
                null, request, response);
    }

    /**
     * 导入
     *
     * @param file
     * @return
     * @throws Exception
     */
    @Override
    public String excelImport(MultipartFile file) throws Exception {
        //获取Excel格式
        int type = readExcel(file.getOriginalFilename());
        Workbook wb = null;
        //获取第一个工作表的数据（其他工作表数据不操作）
        Sheet sheet = null;
        //xls格式
        if (type == 1) {
            wb = new HSSFWorkbook(file.getInputStream());
        } else if (type == 2) {//xlsx格式
            wb = new XSSFWorkbook(file.getInputStream());
        } else {
            throw new BusinessException("请导入正确文件类型");
        }
        if (wb != null && wb.getNumberOfSheets() > 0) {
            for (int i = 0; i < wb.getNumberOfSheets(); i++) {
                if (wb.getSheetAt(i).getPhysicalNumberOfRows() > 0) {
                    sheet = wb.getSheetAt(i);
                    break;
                }
            }
        } else {
            throw new BusinessException("导入失败");
        }
        //判断第一行的第1、2列的名称，不符合则提示模板文件不对
        Row r = sheet.getRow(0);
        if (!r.getCell(0).getStringCellValue().equals("内容")
                || !r.getCell(1).getStringCellValue().equals("喜欢人数") ||
                !r.getCell(2).getStringCellValue().equals("备注")) {
            throw new BusinessException("请选择正确的模板文件再导入");
        }
        List<JokesEntity> list = new ArrayList<>();
        for (int i = 1, length = sheet.getLastRowNum(); i <= length; i++) {
            Row row = sheet.getRow(i);
            //判断第1，2列是否有空值
            if (
                    row.getCell(0) == null
            ) {
                throw new BusinessException("部分数据导入成功<br>,已导入到第" + i + "行,在【" + (i + 1) + "】行有空数据");
            }
            JokesEntity entity = new JokesEntity();
            entity.setTEXT(row.getCell(0).getStringCellValue());
            if(null != row.getCell(1)){
                entity.setLove(Integer.valueOf(row.getCell(1).getStringCellValue()));
            }
            if(null != row.getCell(2)){
                entity.setRemark(row.getCell(2).getStringCellValue());
            }
            entity.setDeleted(1);
            list.add(entity);
        }
        this.saveBatch(list);
        return "导入成功";
    }

    /**
     * 读取excel格式
     *
     * @param fileName
     * @return
     * @throws Exception
     */
    private int readExcel(String fileName) {
        String extString = fileName.substring(fileName.lastIndexOf("."));
        try {
            if (".xls".equals(extString)) {
                return 1;
            } else if (".xlsx".equals(extString)) {
                return 2;
            } else {
                return 0;
            }
        } catch (Exception e) {
            log.error("读取Excel文件异常" + e);
            throw new BusinessException("读取Excel文件异常");
        }
    }

    /**
     * 异步爬虫爬取中关村数据
     *
     * @param reptilesVo
     * @return
     * @throws IOException
     */
    @Async
    @Override
    public void listSave(ReptilesVo reptilesVo) throws IOException {
        List<JokesEntity> list = new ArrayList<>();
        for (int i = reptilesVo.getStart(); i <= reptilesVo.getEnd(); i++) {
            JokesEntity joke = new JokesEntity();
            Connection connection_context = Jsoup
                    .connect("http://xiaohua.zol.com.cn/detail60/" + i + ".html")
                    .userAgent("Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)")
                    .timeout(3000);
            Connection connection_likeAndHate = Jsoup
                    .connect("http://xiaohua.zol.com.cn/index.php?c=Ajax_Xiaohua&a=XhVoteGoodBad&xhId=" + i)
                    .userAgent("Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)")
                    .timeout(3000);
            try {
                if (connection_context.execute().statusCode() == 200) {
                    Document document_context = connection_context.get();
                    //笑话正文
                    String text = getText(document_context);
                    //若没有正文则返回
                    if (text == null || text.trim().length() == 0) {
                        log.info("地址" + i + "：没有内容或者内容为图片");
                    }
                    joke.setTEXT(text);
                    //赞和踩
                    if (connection_likeAndHate.execute().statusCode() == 200) {
                        Document document_likeAndHate = connection_likeAndHate.get();
                        List<String> likeAndHate = getLikeAndHate(document_likeAndHate, i);
                        String likes = likeAndHate.get(0);
                        String hates = likeAndHate.get(1);
                        joke.setLove(Integer.parseInt(likes));
                    }
                    joke.setDeleted(1);
                    log.info("地址" + i + ": OK ");
                    log.info(JSON.toJSONString(joke));
                } else {
                    log.error("地址" + i + ": 不可用");
                }
            } catch (Exception ex) {
                log.error("地址" + i + ": 不可用");
            }
            if(StrUtil.isNotEmpty(joke.getTEXT())){
                list.add(joke);
            }
        }
        this.remove(null);
        this.saveBatch(list);
    }

    /**
     * 获取笑话题目
     *
     * @param document
     * @return
     */
    private String getTitle(Document document) {
        Elements title = document
                .select(".wrapper")
                .select(".clearfix")
                .select(".main")
                .select(".section")
                .select(".article")
                .select(".article-header")
                .select("h1");
        return title.first().text();
    }

    /**
     * 获取笑话来源
     *
     * @param document
     * @return
     */
    private String getSource(Document document) {
        Elements source = document
                .select(".wrapper")
                .select(".clearfix")
                .select(".main")
                .select(".section")
                .select(".article")
                .select(".article-header")
                .select(".article-source");
        String[] split = source.text().split("：");
        if (split.length >= 2) {
            return source.text().split("：")[1];
        } else {
            return "";
        }
    }

    /**
     * 获取笑话正文
     *
     * @param document
     * @return
     */
    private String getText(Document document) {
        Elements text = document
                .select(".wrapper")
                .select(".clearfix")
                .select(".main")
                .select(".section")
                .select(".article")
                .select(".article-text");
        return text.text();
    }

    /**
     * 获取赞和踩
     *
     * @param document_likeAndHate
     * @param addressId
     * @return
     * @throws IOException
     */
    private List<String> getLikeAndHate(Document document_likeAndHate, int addressId) throws IOException {
        Elements body = document_likeAndHate.select("body");
        try {
            Map map = JSON.parseObject(body.text(), Map.class);
            List<String> likeAndHate = (List<String>) map.get(addressId + "");
            return likeAndHate;
        } catch (Exception e) {
            List<String> list = new ArrayList<String>();
            list.add("0");
            list.add("0");
            return list;
        }
    }

    /**
     * 获取属性名
     *
     * @param document
     * @return
     */
    private String getTypeName(Document document) {
        Elements elements = document
                .select(".wrapper")
                .select(".location")
                .select(".clearfix")
                .select("a");
        return elements.get(3).text();
    }


}